<?php

use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Payment\Pay;
use Payment\Notify;
use Qiniu\Sms;
use SliderCapcha\SliderCapcha;
use PHPMailer\PHPMailer\PHPMailer;

class IndexController extends CCommonController
{
    public function indexAction()
    {
        redirect('/members/index');
    }

    public function loginAction()
    {
        if ($this->isPost()) {
            $memberRows = [
                'username'   => $this->get('mobile'),
                'password'   => $this->get('password'),
            ];
            $roles      = [
                'username' => ['role' => "required|exists:members.phone", 'func' => 'isMobile', 'msg' => '手机号'],
                'password' => ['role' => "required", 'msg' => '登陆密码'],
            ];
            Validate::check($memberRows, $roles);
            $mem = new membersModel;
            if(!$mem->checkPassword($memberRows['username'], $memberRows['password'])){
                ret(3, '账号密码有误');
            }
            if(!$mem->checkStatus($memberRows['username'])){
                ret(4, '账号已冻结');
            }
            if($mem->setLogin($memberRows['username'], $memberRows['password'])){
                ret(0, '登陆成功');
            }else{
                ret(5, '登陆失败,请联系客服');
            }
        } else {
            $this->_view->assign('host', $_SERVER['HTTP_HOST']);
            $this->_view->display('main/login.html');
        }
    }

    public function registerAction()
    {
        if ($this->isPost()) {
            do {
                $companyRows = [
                    'name'       => $this->get('company'),
                    'code'       => randStr(11, 1),
                    'catalog_id' => $this->get('catalog_id'),
                    'status'     => 0,
                    'created_at' => date('Y-m-d H:i:s')
                ];
                $roles       = [
                    'name' => ['role' => "required", 'msg' => '公司名称'],
                ];
                Validate::check($companyRows, $roles);
                $ip         = getIp();
                $date       = date("Y-m-d H:i:s");
                $token = md5($this->get('mobile') . $ip . $date . $this->get('password'));
                $memberRows = [
                    'username'   => $this->get('mobile'),
                    'phone'      => $this->get('mobile'),
                    'password'   => $this->get('password'),
                    'score'      => 100,
                    'rank_id'    => 6,
                    'token'      => $token,
                    'status'     => 1,
                    'logined_ip' => $ip,
                    'logined_at' => $date,
                    'created_at' => $date,
                ];
                $roles      = [
                    'phone'    => ['role' => "required|unique:members.phone", 'func' => 'isMobile', 'msg' => '主账号'],
                    'password' => ['role' => "required", 'msg' => '登陆密码'],
                ];
                Validate::check($memberRows, $roles);
                try {
                    DB::beginTransaction();
                    $db = DB::table('company')->max('db');
                    if(DB::table('products_'.$db)->count()>=MAXROWS){
                        ++$db;
                        if(!DB::schema()->hasTable('products_'.$db)){
                            DB::schema()->create('products_'.$db, function (Blueprint $table) {
                                $table->engine = 'InnoDB';
                                $table->charset= 'utf8';
                                $table->collation = 'utf8_general_ci';
                                $table->increments('id');
                                $table->integer('company_id')->unsigned()->index();
                                $table->string('title', 255)->index();
                                $table->string('logo', 255)->default('');
                                $table->string('class', 255)->default('');
                                $table->integer('cat_level1')->default(0);
                                $table->integer('cat_level2')->default(0);
                                $table->integer('cat_level3')->default(0);
                                $table->string('price', 32)->default('');
                                $table->string('keywords', 255)->default('');
                                $table->integer('hits')->default(0);
                                $table->boolean('status')->default(0);
                                $table->integer('sortorder')->default(500);
                                $table->timestamps();
                            });
                            DB::schema()->create('products_info_'.$db, function (Blueprint $table) {
                                $table->engine = 'InnoDB';
                                $table->charset= 'utf8';
                                $table->collation = 'utf8_general_ci';
                                $table->integer('products_id')->index();
                                $table->string('images', 2000)->default('');
                                $table->text('params')->nullable();
                                $table->text('detail')->nullable();
                            });
                        }
                    }
                    $companyRows['db'] = $db;
                    $company_id     = DB::table('company')->insertGetId($companyRows);
                    $companyInfoRow = [
                        'company_id'    => $company_id,
                        'audit_company' => 0,
                        'audit_members' => 0,
                        'audit_email'   => 0,
                        'audit_phone'   => 0,
                    ];
                    DB::table('company_info')->insert($companyInfoRow);
                    $memberRows['password']   = md5($memberRows['password']);
                    $memberRows['company_id'] = $company_id;
                    $members_id               = DB::table('members')->insertGetId($memberRows);
                    $membersInfoRow           = [
                        'members_id' => $members_id,
                        'company_id' => $company_id,
                        'contact'    => $this->get('contact'),
                        'tel'        => $this->get('tel'),
                    ];
                    DB::table('members_info')->insert($membersInfoRow);
                    DB::commit();
                    if((new membersModel)->setLogin($memberRows['username'], $this->get('password'))) {
                        $result = [
                            'ret' => 0,
                            'msg' => '操作成功'
                        ];
                    }else{
                        $result = [
                            'ret' => 2,
                            'msg' => '登陆失败'
                        ];
                    }
                } catch (\Throwable $e) {
                    DB::rollBack();
                    $result = [
                        'ret'  => 3,
                        'msg'  => '执行失败',
                        'data' => $e->getMessage(),
                    ];
                }
            } while (FALSE);
            json($result);
        } else {
            $step = $this->get('step', 1);
            if ($step == 2) {
                $mainCata = DB::table('catalog')->where('up', '=', 0)->orderBy('sortorder', 'desc')->get();
                $this->_view->assign('mainCata', $mainCata);
            }
            $this->_view->assign('host', $_SERVER['HTTP_HOST']);
            $this->_view->display('main/register' . $step . '.html');
        }
    }

    public function getCatAction()
    {
        $up = $this->get('up', 0);
        ret(0, 'ok', DB::table('catalog')->where('up', $up)->orderBy('sortorder', 'desc')->pluck('name', 'id'));
    }

    public function getCityAction()
    {
        $up = $this->get('up', 0);
        ret(0, 'ok', DB::table('sys_city')->where('up', $up)->orderBy('sortorder', 'desc')->pluck('name', 'id'));
    }

    public function qrcodeAction()
    {
        $url = urldecode($this->get("data", ''));
        QRcode::png($url, false, 1, 4);
    }

    public function sendSmsAction()
    {
        if (empty($this->get('smstoken')) || empty($this->session->get('smstoken')) || $this->session->get('smstoken') != $this->get('smstoken')) {
            ret(200, '验证失败');
        }
        $this->session->del('smscode');
        $inputs = [
            'mobile' => $this->get('mobile')
        ];
        /***参数验证BOF***/
        $roles = [
            'mobile' => ['role' => 'required', 'func' => "isMobile", 'msg' => '手机号'],
        ];
        Validate::check($inputs, $roles);
        if (DB::table('sms_code')->where('mobile', $inputs['mobile'])->where('created_at', '>', date('Y-m-d 00:00:00'))->count() >= 5) {
            ret(200, '发送次数超限');
        }
        // 需要填写你的 Access Key 和 Secret Key
        $accessKey = $this->config['application']['sms']['accessKey'];
        $secretKey = $this->config['application']['sms']['secretKey'];
        // 构建鉴权对象
        $auth   = new \Qiniu\Auth($accessKey, $secretKey);
        $sms    = new Sms\Sms($auth);
        $code   = rand(1000, 9999);
        $params = [
            $this->config['application']['sms']['template_id'],
            [$inputs['mobile']],
            ['code' => $code]
        ];
        $ret    = $sms->sendMessage(...$params)[0];
        if (isset($ret['job_id'])) {
            $rows = [
                'mobile'     => $inputs['mobile'],
                'code'       => $code,
                'created_at' => date('Y-m-d H:i:s')
            ];
            DB::table('sms_code')->insert($rows);
            ret(0, '发送成功');
        } else {
            ret(300, '发送失败');
        }
    }

    public function sendMailAction()
    {
        if (empty($this->get('smstoken')) || empty($this->session->get('smstoken')) || $this->session->get('smstoken') != $this->get('smstoken')) {
            ret(200, '验证失败');
        }
        $this->session->del('smscode');
        $inputs = [
            'email' => $this->get('email')
        ];
        /***参数验证BOF***/
        $roles = [
            'email' => ['role' => 'required', 'func' => "isEmail", 'msg' => '邮箱'],
        ];
        Validate::check($inputs, $roles);
        if (DB::table('sms_code')->where('mobile', $inputs['email'])->where('created_at', '>', date('Y-m-d 00:00:00'))->count() >= 10) {
            ret(200, '发送次数超限');
        }
        $code   = rand(1000, 9999);
        if ($this->sendMail($inputs['email'], $code)) {
            $rows = [
                'mobile'     => $inputs['email'],
                'code'       => $code,
                'created_at' => date('Y-m-d H:i:s')
            ];
            DB::table('sms_code')->insert($rows);
            ret(0, '发送成功');
        } else {
            ret(300, '发送失败');
        }
    }

    private function sendmail($email, $code)
    {
        $emailServer = DB::table('email_server')->where('default', 1)->first();
        if(!$emailServer){
            return false;
        }
        $mail = new PHPMailer;
        $mail->isSMTP();
        $mail->SMTPDebug = 0;
        $mail->Host = $emailServer->Host;
        $mail->Port = $emailServer->Post;
        $mail->SMTPAuth = true;
        $mail->Username = $emailServer->Username;
        $mail->Password = $emailServer->Password;
        $mail->setFrom($emailServer->Username, 'customer service');
        $mail->addAddress($email, 'curr.cn Member');
        $mail->Subject = '与时信息网';
        $mail->Body = '您的验证码为：' . $code . ', 该验证码5分钟内有效，请勿泄露给他人。';
        return $mail->send();
    }

    public function makeAction()
    {
        $config['dir'] = APP_PATH . '/public/plugins/slide-capcha/bg/';
        $sc            = new SliderCapcha($config);
        $sc->make();
    }

    public function checkSlideAction()
    {
        do {
            if (!SliderCapcha::check()) {
                $result = [
                    'ret' => 1,
                    'msg' => '滑动验证失败.',
                ];
            } else {
                $smstoken = uniqid('sms');
                $this->session->set('smstoken', $smstoken);
                $result = [
                    'ret'  => 0,
                    'msg'  => '滑动验证成功.',
                    'data' => [
                        'smstoken' => $smstoken,
                    ]
                ];
            }
        } while (FALSE);
        json($result);
    }

    public function checkVerifyCodeAction()
    {
        $inputs = [
            'mobile' => $this->get('mobile/s'),
            'code'   => $this->get('code/s'),
        ];
        /***参数验证BOF***/
        $roles = [
            'mobile' => ['role' => 'required', 'func' => "isMobile", 'msg' => '手机号'],
            'code'   => ['role' => 'required|length:4', 'msg' => '验证码'],
        ];
        Validate::check($inputs, $roles);
        if($this->config['application']['debug']){
            ret(0, '验证码可能正确');
        }
        $row = DB::table('sms_code')->where('mobile', $inputs['mobile'])->where('created_at', '>', date('Y-m-d H:i:s', time() - 1200))->orderby('created_at', 'DESC')->first();
        if ($row->code !== $inputs['code']) {
            ret(100, '验证码错误或已过期');
        } else {
            ret(0, '验证码正确');
        }
    }

    public function uptokenAction()
    {
        // 需要填写你的 Access Key 和 Secret Key
        $accessKey = $this->config['application']['cdn']['accessKey'];
        $secretKey = $this->config['application']['cdn']['secretKey'];

        // 构建鉴权对象
        $auth = new \Qiniu\Auth($accessKey, $secretKey);
        // 要上传的空间
        $bucket = $this->config['application']['cdn']['bucket'];

        // 生成上传 Token
        $token = $auth->uploadToken($bucket);
        die('{"uptoken":"' . $token . '"}');
    }

    public function disclaimerAction()
    {
        $this->_view->display('main/disclaimer.html');
    }

    public function productsinfoAction(){
        $code = base32_decode($this->get('code/s'));
        if(!preg_match('#\d+_\d+#', $code)){
            throw new Exception('404 not found', 404);
        }
        [$db, $id] = explode('_', $code);
        $db = intval($db);
        $id = intval($id);
        if(empty($db)||empty($id)){
            throw new Exception('404 not found', 404);
        }
        $dba = 'products_' . $db;
        $products = DB::table($dba)->whereIn('status', [1, 2])->where('id', $id)->first();
        if(!$products){
            throw new Exception('产品已下架或被删除', 404);
        }
        $corp = (new companyModel)->where('id', $products->company_id)->first()->toArray();
        if($corp) {
            $this->_view->assign('dataset', object_to_array($corp));
            $products_list = DB::table($dba)->where('company_id', $corp['id'])->where('status', 1)->orderBy('created_at', 'desc')->limit(7)->get()->toArray();
            $this->_view->assign('products', object_to_array($products_list));
        }else{
            throw new Exception('404 not found', 404);
        }
        if($products){
            DB::table($dba)->where('status', 1)->where('id', $id)->increment('hits');
            $this->_view->assign('main', object_to_array($products));
            $dbb  = 'products_info_' . $db;
            $info = DB::table($dbb)->where('products_id', $id)->first();
            $info->params = empty($info->params) ? [] : json_decode($info->params, true);
            $info->desc   = mb_substr(strip_tags($info->detail), 0, 200);
            $this->_view->assign('info', object_to_array($info));
            $goodsnum = DB::table($dba)->where('company_id', $corp['id'])->where('status', 1)->count();
            $this->_view->assign('goodsnum', $goodsnum);
            $this->_view->display('main/productsinfo.html');
        }else{
            throw new Exception('404 not found', 404);
        }
    }

    public function newestAction()
    {
        $page     = $this->get('page', 1);
        $limit    = 10;
        $offset   = ($page - 1) * $limit;
        $maps     = [];
        $keywords = $this->getPost('keywords', '');
        if ($keywords !== '') {
            array_push($maps, ['title', 'like', "%{$keywords}%"]);
        }
        $maxDb  = DB::table('company')->max('db');
        $query  = DB::table('products_1')->where($maps)->where('status', 1);
        for ($i = 2; $i <= $maxDb; ++$i) {
            $subQuery = DB::table('products_' . $i)->where($maps)->where('status', 1);
            $query = $query->unionAll($subQuery);
        }
        $total = $query->count();
        $rows  = $query->orderBy('created_at', 'desc')
            ->offset($offset)
            ->limit($limit)
            ->get()->toArray();
        foreach ($rows as $k => $v) {
            $com                = DB::table('company')->find($v->company_id);
            $v->company_name    = $com->name;
            $v->to              = base32_encode($com->db . '_' . $v->id);
        }
        $this->_view->assign('pager', $total>0 ? (new Pager($total, 10, $page))->getPager() : '');
        $this->_view->assign('allproducts', object_to_array($rows));

        $maxDb  = DB::table('company')->max('db');
        $query  = DB::table('products_1')->where('status', 2);
        for ($i = 2; $i <= $maxDb; ++$i) {
            $subQuery = DB::table('products_' . $i)->where('status', 2);
            $query = $query->unionAll($subQuery);
        }
        $rows  = $query->orderBy('created_at', 'desc')->limit(30)->get()->toArray();
        foreach ($rows as $k => $v) {
            $db                = DB::table('company')->where('id', $v->company_id)->value('db');
            $v->to              = base32_encode($db . '_' . $v->id);
        }
        $this->_view->assign('recoproducts', object_to_array($rows));

        $company = DB::select('SELECT * FROM `co_company` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `co_company`)-
                    (SELECT MIN(id) FROM `co_company`))+(SELECT MIN(id) FROM `co_company`)) AS id) AS t2 WHERE t1.status=1 and t1.id >= t2.id
                    ORDER BY t1.id LIMIT 30');
        $this->_view->assign('company', object_to_array($company));
        $this->_view->display('main/newest.html');
    }

}
